home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Tools / Win95 Secrets / SETUP.Z / HOOKAPI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-19  |  4.9 KB  |  134 lines

  1. //==================================
  2. // SIMONSEZ - Matt Pietrek 1995
  3. // FILE: HOOKAPI.C
  4. //==================================
  5. #include <windows.h>
  6. #include <string.h>
  7. #include "hookapi.h"
  8.  
  9. // Macro for adding pointers/DWORDs together without C arithmetic interfering
  10. #define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr)+(DWORD)(addValue))
  11.  
  12. DWORD GetModuleBaseFromWin32sHMod(HMODULE hMod); // Prototype (defined below)
  13.  
  14. PROC WINAPI HookImportedFunction(
  15.         HMODULE hFromModule,        // Module to intercept calls from
  16.         PSTR    pszFunctionModule,  // Module to intercept calls to
  17.         PSTR    pszFunctionName,    // Function to intercept calls to
  18.         PROC    pfnNewProc          // New function (replaces old function)
  19.         )
  20. {
  21.     PROC pfnOriginalProc;
  22.     PIMAGE_DOS_HEADER pDosHeader;
  23.     PIMAGE_NT_HEADERS pNTHeader;
  24.     PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
  25.     PIMAGE_THUNK_DATA pThunk;
  26.  
  27.     if ( IsBadCodePtr(pfnNewProc) ) // Verify that a valid pfn was passed
  28.         return 0;
  29.     
  30.     // First, verify the the module and function names passed to use are valid
  31.     pfnOriginalProc = GetProcAddress( GetModuleHandle(pszFunctionModule),
  32.                                       pszFunctionName );
  33.     if ( !pfnOriginalProc )
  34.         return 0;
  35.     
  36.     if ( (GetVersion() & 0xC0000000) == 0x80000000 )
  37.         pDosHeader =                                            // Win32s
  38.             (PIMAGE_DOS_HEADER)GetModuleBaseFromWin32sHMod(hFromModule);
  39.     else
  40.         pDosHeader = (PIMAGE_DOS_HEADER)hFromModule;            // other
  41.  
  42.     // Tests to make sure we're looking at a module image (the 'MZ' header)
  43.     if ( IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)) )
  44.         return 0;
  45.     if ( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )
  46.         return 0;
  47.  
  48.     // The MZ header has a pointer to the PE header
  49.     pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew);
  50.  
  51.     // More tests to make sure we're looking at a "PE" image
  52.     if ( IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) )
  53.         return 0;
  54.     if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE )
  55.         return 0;
  56.  
  57.     // We know have a valid pointer to the module's PE header.  Now go
  58.     // get a pointer to its imports section
  59.     pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDosHeader, 
  60.                             pNTHeader->OptionalHeader.
  61.                             DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
  62.                             VirtualAddress);
  63.                         
  64.     // Bail out if the RVA of the imports section is 0 (it doesn't exist)
  65.     if ( pImportDesc == (PIMAGE_IMPORT_DESCRIPTOR)pNTHeader )
  66.         return 0;
  67.  
  68.     // Iterate through the array of imported module descriptors, looking
  69.     // for the module whose name matches the pszFunctionModule parameter
  70.     while ( pImportDesc->Name )
  71.     {
  72.         PSTR pszModName = MakePtr(PSTR, pDosHeader, pImportDesc->Name);
  73.         
  74.         if ( stricmp(pszModName, pszFunctionModule) == 0 )
  75.             break;
  76.  
  77.         pImportDesc++;  // Advance to next imported module descriptor
  78.     }
  79.     
  80.     // Bail out if we didn't find the import module descriptor for the
  81.     // specified module.  pImportDesc->Name will be non-zero if we found it.
  82.     if ( pImportDesc->Name == 0 )
  83.         return 0;
  84.  
  85.     // Get a pointer to the found module's import address table (IAT)
  86.     pThunk = MakePtr(PIMAGE_THUNK_DATA, pDosHeader, pImportDesc->FirstThunk);
  87.  
  88.     // Blast through the table of import addresses, looking for the one
  89.     // that matches the address we got back from GetProcAddress above.
  90.     while ( pThunk->u1.Function )
  91.     {
  92.         if ( pThunk->u1.Function == (PDWORD)pfnOriginalProc )
  93.         {
  94.             // We found it!  Overwrite the original address with the
  95.             // address of the interception function.  Return the original
  96.             // address to the caller so that they can chain on to it.
  97.             pThunk->u1.Function = (PDWORD)pfnNewProc;
  98.             return pfnOriginalProc;
  99.         }
  100.         
  101.         pThunk++;   // Advance to next imported function address
  102.     }
  103.     
  104.     return 0;   // Function not found
  105. }
  106.  
  107. typedef DWORD (__stdcall *XPROC)(DWORD);
  108.  
  109. // Converts an HMODULE under Win32s to a base address in memory
  110. DWORD GetModuleBaseFromWin32sHMod(HMODULE hMod)
  111. {
  112.     XPROC ImteFromHModule, BaseAddrFromImte;
  113.     HMODULE hModule;
  114.     DWORD imte;
  115.     
  116.     hModule = GetModuleHandle("W32SKRNL.DLL");
  117.     if( !hModule )
  118.         return 0;
  119.     
  120.     ImteFromHModule = (XPROC)GetProcAddress(hModule, "_ImteFromHModule@4");
  121.     if ( !ImteFromHModule )
  122.         return 0;
  123.     
  124.     BaseAddrFromImte = (XPROC)GetProcAddress(hModule, "_BaseAddrFromImte@4");
  125.     if ( !BaseAddrFromImte )
  126.         return 0;
  127.  
  128.     imte = ImteFromHModule( (DWORD)hMod);
  129.     if ( !imte )
  130.         return 0;
  131.     
  132.     return BaseAddrFromImte(imte);
  133. }
  134.